/**
    ATClab - scriptable Air Traffic Control simulations.
    Copyright (C) 2010 openatclab@gmail.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
**/

#include "taskwidget.h"

#include "trialtask.h"
#include "logger.h"

#include <qapplication.h>
//#include <qhbuttongroup.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qlineedit.h>
#include <qobject.h> 
#include <qtimer.h>
#include <q3widgetstack.h>
//Added by qt3to4:
#include <Q3GridLayout>
#include <QShowEvent>
#include <Q3BoxLayout>
#include <QHideEvent>
#include <Q3HBoxLayout>
#include <Q3VBoxLayout>
#include <Q3Frame>
#include <QKeyEvent>

#ifdef _WIN32
	#include <assert.h>
#endif

using namespace pact;
using std::string;

//==============================================================================
//
// Dialog
//
//------------------------------------------------------------------------------
// Construction/Destruction
//

/*!
 */
Dialog::Dialog( TrialTask *parent, const char *name )
		:QDialog(
				parent, name, false, 
				Qt::WStyle_Customize|Qt::WStyle_DialogBorder|Qt::WStyle_Title
			)
		, _stack( new Q3WidgetStack(this) )
		, _widgetNo( 0 )
		, _interval( 0 )
		, _sshot( 0 )
{
	resize( 0,0 );		// want minimum size!
	Q3GridLayout *mgr = new Q3GridLayout( this );
	mgr->addWidget( _stack, 0, 0 );
}

/*!
 *
 */
Dialog::~Dialog() {
	//hide(); 
}

//------------------------------------------------------------------------------
// [public]
//

/*!
 *
 */
void Dialog::addWidget( QWidget *w ) {

	Q3Frame *frame = new Q3Frame( this );
	//frame->setFrameStyle( QFrame::Box|QFrame::Plain );

	w->reparent( frame, 0, QPoint(), FALSE);

	Q3BoxLayout *vbox = new Q3VBoxLayout( frame );
	vbox->addStretch();
	Q3BoxLayout *hbox = new Q3HBoxLayout( vbox );
	vbox->addStretch();

	hbox->addStretch();
	hbox->addWidget( w );
	hbox->addStretch();

	_stack->addWidget( frame, _widgetNo++ );

	connect( w, SIGNAL( accepted() ), this, SLOT( process_stack() ) );
}

/*!
 *
 */
void Dialog::_setLocation() {

	const int MARGIN = 10;
	
	QWidget *parent = dynamic_cast< QWidget * >( this->parent() );
	QSize pwin = parent->size();
	QSize dwin = this->frameSize();

	int _x, _y;

	if      ( string::npos != _location.find( "TOP" ) )    _y = MARGIN;
	else if ( string::npos != _location.find( "BOTTOM" ) ) _y = pwin.height() - dwin.height() - MARGIN;
	else                                                   _y = (pwin.height() - dwin.height()) / 2;
	
	if      ( string::npos != _location.find( "LEFT" ) )   _x = MARGIN;
	else if ( string::npos != _location.find( "RIGHT" ) )  _x = pwin.width() - dwin.width() - MARGIN;
	else                                                   _x = (pwin.width() - dwin.width()) / 2;
 
	move( _x, _y );
}

//------------------------------------------------------------------------------
// [public] slots
//

/*!
 *
 */
void Dialog::reset_timer() {
	if ( _interval ) {
		TrialTask *tt = dynamic_cast< TrialTask * >( parent() );
		tt->set_timer( _interval, this, SLOT(show()) );
		if ( _sshot ) _interval = 0;
	}
}


//------------------------------------------------------------------------------
// [protected] virtual
//

/*!
 *
 */
void Dialog::keyPressEvent( QKeyEvent *e ) {
	QObject* target = parentWidget()->child( TrialTask::MAIN_TARGET );
	QKeyEvent* keyevent = new QKeyEvent(
		QKeyEvent::KeyPress,
		e->key(),
		e->ascii(),
		e->state(),
		e->text(),
		e->isAutoRepeat(),
		e->count()
	);
	QApplication::postEvent( target, keyevent );
}

/*!
 *
 */
void Dialog::showEvent( QShowEvent *e ) {

	_setLocation();

	// content
	_stack->raiseWidget( 0 );

	//done
	emit shown();
}

/*!
 *
 */
void Dialog::hideEvent( QHideEvent *e ) {
	reset_timer();
	emit hidden();
}

//------------------------------------------------------------------------------
// [private slots]
//

/*!
 *
 */
void Dialog::log_state() {
	logging::KVPairs kvs;
	kvs.push_back(std::make_pair(
		std::string("elapsed"), 
		QString("%1").arg(dynamic_cast<Task*>(parent())->time()).latin1() 
	));
	kvs.push_back(std::make_pair(std::string("Dialog::log_state"), name()));
	kvs.push_back(std::make_pair(sender()->name(), std::string("clicked")));


	foreach (QLineEdit* obj, findChildren<QLineEdit*>()) { // iterate over the buttons
		kvs.push_back(std::make_pair(obj->name(), ((QLineEdit*)obj)->text()));
	}

	logging::Logger::instance()->info(kvs);
}


/*!
 *
 */
void Dialog::process_stack() {
	log_state();
	int id = _stack->id( _stack->visibleWidget() );
	if ( ++id < _widgetNo ) _stack->raiseWidget( id );
	else hide();
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//
// PushButton
//
////////////////////////////////////////////////////////////////////////////////////////////////////
// Construction/Destruction
//

/*!
 *
 */
PushButton::PushButton(QWidget* parent, const char* name)
	:QPushButton(parent, name)
{
	setFocusPolicy(Qt::NoFocus);
	setDefault(false);
	setAutoDefault(false);
}

PushButton::~PushButton()
{}

////////////////////////////////////////////////////////////////////////////////////////////////////
